package dp.gr03.payroll.application.commands;

import java.util.HashMap;

import dp.gr03.payroll.exception.InvalidArgumentsException;
import dp.gr03.payroll.exception.PayRollException;
import dp.gr03.payroll.payrollApplication.Transaction;
import dp.gr03.payroll.transactionFactory.TransactionFactoryImplementation;

public class AddEmployeeCommand implements TransactionParser
{
    protected HashMap<String, AddEmployeeTypeCommand> types;
    protected int employeeId;
    protected String employeeName;
    protected String employeeAddress;
    protected String employeeType;

    public AddEmployeeCommand()
    {
        this.types = new HashMap<String, AddEmployeeTypeCommand>();
        types.put("H", new AddHourlyEmployeeCommand());
        types.put("S", new AddSalariedEmployeeCommand());
        types.put("C", new AddCommissionedEmployeeCommand());
    }

    public String getActionString()
    {
        return "AddEmp";
    }

    public Transaction parse(String[] arguments) throws PayRollException
    {
        if (arguments.length >= 6)
        {
            try
            {
                employeeId = Integer.parseInt(arguments[1]);
                Double.parseDouble(arguments[5]);
                if (arguments.length == 7)
                {
                    Double.parseDouble(arguments[6]);
                }
            } catch (NumberFormatException e)
            {
                throw new PayRollException("Employee ID, hourly rate, monthly salary and commission rate should be numbers");
            }
            employeeName = arguments[2];
            employeeAddress = arguments[3];
            employeeType = arguments[4];

            AddEmployeeTypeCommand command = types.get(employeeType);
            if (command == null)
            {
                throw new PayRollException("This employee type doesn't exist.");
            }

            return command.createTransaction(arguments);
        } else
        {
            throw new InvalidArgumentsException("Not enough or invalid arguments supplied");
        }
    }

    private abstract class AddEmployeeTypeCommand
    {
        protected abstract Transaction createTransaction(String[] arguments) throws InvalidArgumentsException;
    }

    private class AddHourlyEmployeeCommand extends AddEmployeeTypeCommand
    {

        @Override
        protected Transaction createTransaction(String[] arguments)
        {
            double hourlyRate = Double.parseDouble(arguments[5]);
            return TransactionFactoryImplementation.getInstance().makeAddHouryEmployee(employeeId, employeeName, employeeAddress, hourlyRate);
        }

    }

    private class AddSalariedEmployeeCommand extends AddEmployeeTypeCommand
    {

        @Override
        protected Transaction createTransaction(String[] arguments)
        {
            double salary = Double.parseDouble(arguments[5]);
            return TransactionFactoryImplementation.getInstance().makeAddSalaryTransaction(employeeId, employeeName, employeeAddress,
                    salary);
        }

    }

    private class AddCommissionedEmployeeCommand extends AddEmployeeTypeCommand
    {

        @Override
        protected Transaction createTransaction(String[] arguments) throws InvalidArgumentsException
        {
            double salary = Double.parseDouble(arguments[5]);
            if (arguments.length < 7)
            {
                throw new InvalidArgumentsException("Not enough or invalid arguments supplied");
            }
            double commissionRate = Double.parseDouble(arguments[6]);
            return TransactionFactoryImplementation.getInstance().makeAddCommisionedTransaction(employeeId, employeeName, employeeAddress, salary, commissionRate);

        }

    }

}
